from PIL import Image, ImageDraw, ImageFont
import pyqrcode
import win32print
import win32ui
from PIL import Image, ImageWin
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import time


class img_assText():
    def __init__(self, img_path, is_print=False, img_savePath='out_.png', text="图片添加文字测试", setFont=r'C:\Windows\Fonts\simhei.ttf', Font_size=20, x=40, y=40):
        size = None
        # gen_img()
        # ** ImageFont模块**
        # 选择文字字体和大小
        self.Font_path = setFont
        self.Font_size = Font_size
        self.x = x
        self.y = y
        self.is_print = False

        setFont = ImageFont.truetype(self.Font_path, self.Font_size)
        # 设置文字颜色
        fillColor = "#0000ff"  # 蓝色
        self.text = text
        size = (40, 40)
        self.filepath = img_path
        self.filename = img_savePath
        # 添加文字
        self.pic_text(self.filepath, size, text, setFont, fillColor, self.filename, direction=None)
        if is_print:
            self.print_img3(self.filename)


    def gen_img(size=None):
        if size is None:
            size = 400
            # 生成大小为400x400RGBA是四通道图像，RGB表示R，G，B三通道，A表示Alpha的色彩空間
        image = Image.new(mode='RGBA', size=(400, 400), color=(255, 55, 55))
        # ImageDraw.Draw 简单平面绘图
        draw_table = ImageDraw.Draw(im=image)
        # 直接显示图片
        # image.show()

    def pic_open(self, filepath):
        # 图片打开与显示
        image = Image.open(filepath)
        return image

    def get_size(self, image):
        # 获取图像的宽和高
        width, height = image.size
        return width, height


    def pic_text(self, filepath, size, text, setFont, fillColor, filename, direction=None):
        print(filepath, size, text, setFont, fillColor)
        # 打开图片
        image = self.pic_open(filepath)
        # 新建绘图对象
        draw = ImageDraw.Draw(image)
        # 显示图片
        draw.text((self.x, self.y), text, font=setFont, fill=fillColor, direction=None)
        # image.show()
        # 保存
        self.pic_save(image, filename)


    def pic_save(self, image, filename):
        # 保存
        image.save(filename)

    def create_bar(self):
        import datetime
        import random
        # 生成箱子码
        # 格式：P190823-K91  [P][日期][-][A-Z][0-9][0-9]
        bar_string = 'P' + datetime.date.today().strftime('%y%m%d') + '-' + str(
            random.choice('ABCDEFGHIGKLMNOPQRSTUVWXYZ')) \
                     + str(random.choice(range(10))) + str(random.choice(range(10)))
        return bar_string

    # 打印二维码
    def print_barcode(self, type):

        bar_string = self.create_bar()        # 生成标识码
        try:
            big_code = pyqrcode.create(bar_string, error='L', version=2, mode='binary')
            big_code.png('./code.png', scale=8)
            img_code = Image.open('code.png')

            size = img_code.size
            img_final = Image.new('RGB', (size[0], size[1] + 35), color=(255, 255, 255))
            img_final.paste(img_code, (0, 0, size[0], size[1]))

            draw = ImageDraw.Draw(img_final)
            font = ImageFont.truetype('AdobeGothicStd-Bold.otf', size=35)
            width, height = draw.textsize(bar_string, font=font)
            draw.text(((size[0] - width) / 2, size[1] - 15), bar_string, fill=(0, 0, 0), font=font)
            img_final.save('./code.png')

            # 然后连接打印机将其打印出来即可
            is_ok = []
            if type == 'box':
                for i in range(4):
                    temp = self.print_img('./code.png')
                    is_ok.append(temp)
            else:
                temp = self.print_img('./code.png')
                is_ok.append(temp)
            # is_ok = True
            print('ok' if np.all(is_ok) else '连接打印机失败')
        except Exception as e:
            print(e)


    def print_img(self, img):
        # 参考 http://timgolden.me.uk/python/win32_how_do_i/print.html#win32print
        print("开始打印")
        try:
            printer_name = win32print.GetDefaultPrinter()
            hDC = win32ui.CreateDC()
            hDC.CreatePrinterDC(printer_name)

            # printable_area = (300, 270)  # 打印纸尺寸
            # printer_size = (300, 270)

            # 打开图片并缩放
            bmp = Image.open(img)
            if bmp.size[0] < bmp.size[1]:
                bmp = bmp.rotate(90)

            # ratios = [1.0 * printable_area[0] / bmp.size[1], 1.0 * printable_area[1] / bmp.size[0]]
            # scale = min(ratios)
            scale = 1

            hDC.StartDoc(img)
            hDC.StartPage()

            dib = ImageWin.Dib(bmp)
            scaled_width, scaled_height = [int(scale * i) for i in bmp.size]

            x1 = 20  # 控制位置
            y1 = -30
            x2 = x1 + scaled_width
            y2 = y1 + scaled_height
            dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))

            hDC.EndPage()
            hDC.EndDoc()
            hDC.DeleteDC()

            return True
        except:
            return False

    def print_img2(self, img):
        import win32print
        import win32ui
        from PIL import Image, ImageWin

        #
        # Constants for GetDeviceCaps
        #
        #
        # HORZRES / VERTRES = printable area
        #
        HORZRES = 8
        VERTRES = 10
        #
        # LOGPIXELS = dots per inch
        #
        LOGPIXELSX = 88
        LOGPIXELSY = 90
        #
        # PHYSICALWIDTH/HEIGHT = total area
        #
        PHYSICALWIDTH = 110
        PHYSICALHEIGHT = 111
        #
        # PHYSICALOFFSETX/Y = left / top margin
        #
        PHYSICALOFFSETX = 112
        PHYSICALOFFSETY = 113

        printer_name = win32print.GetDefaultPrinter()
        file_name = self.filename

        #
        # You can only write a Device-independent bitmap
        #  directly to a Windows device context; therefore
        #  we need (for ease) to use the Python Imaging
        #  Library to manipulate the image.
        #
        # Create a device context from a named printer
        #  and assess the printable size of the paper.
        #
        hDC = win32ui.CreateDC()
        hDC.CreatePrinterDC(printer_name)
        printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)
        printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
        printer_margins = hDC.GetDeviceCaps(PHYSICALOFFSETX), hDC.GetDeviceCaps(PHYSICALOFFSETY)

        #
        # Open the image, rotate it if it's wider than
        #  it is high, and work out how much to multiply
        #  each pixel by to get it as big as possible on
        #  the page without distorting.
        #
        bmp = Image.open(file_name)
        if bmp.size[0] > bmp.size[1]:
            bmp = bmp.rotate(90)

        ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
        scale = min(ratios)

        #
        # Start the print job, and draw the bitmap to
        #  the printer device at the scaled size.
        #
        hDC.StartDoc(file_name)
        hDC.StartPage()

        dib = ImageWin.Dib(bmp)
        scaled_width, scaled_height = [int(scale * i) for i in bmp.size]
        x1 = int((printer_size[0] - scaled_width) / 2)
        y1 = int((printer_size[1] - scaled_height) / 2)
        x2 = x1 + scaled_width
        y2 = y1 + scaled_height
        dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))

        hDC.EndPage()
        hDC.EndDoc()
        hDC.DeleteDC()

    def print_img3(self, img):
        import win32print
        import win32ui
        from PIL import Image, ImageWin

        # printer_name是默认打印机的名字
        printer_name = win32print.GetDefaultPrinter()
        # 调用打印机打印两张图片
        for i in range(2):
            hDC = win32ui.CreateDC()
            hDC.CreatePrinterDC(printer_name)

            # 打开图片
            bmp = Image.open(img)

            scale = 1
            w, h = bmp.size
            print("开始打印")
            time.sleep(1)
            hDC.StartDoc(img)
            hDC.StartPage()

            dib = ImageWin.Dib(bmp)

            # (10,10,1024,768)前面的两个数字是坐标，后面两个数字是打印纸张的大小
            dib.draw(hDC.GetHandleOutput(), (10, 10, 1024, 768))

            hDC.EndPage()
            hDC.EndDoc()
            hDC.DeleteDC()


if __name__ == "__main__":
    img_assText(img_path='img/empty.png', is_print=True, text="统一归集佛迪士尼", img_savePath='123.png', x=300, y=500)